#ifndef SRC_S2E_PLUGINS_PYTHON_PYTHONOBJECTS_H_
#define SRC_S2E_PLUGINS_PYTHON_PYTHONOBJECTS_H_

#include "Instruction.h"
#include <s2e/S2EExecutionState.h>
#include <Python.h>

namespace s2e {
  namespace plugins {
    namespace python {
      PyObject* PyInstruction(void);

      PyObject* PyInstruction(const s2e::plugins::Instruction& inst);

      PyObject* PyInstruction(const s2e::uint8* opcodes, s2e::uint32 opSize);

      /* Instruction ==================================================== */
      //! pyInstruction object.
      typedef struct {
        PyObject_HEAD
		s2e::plugins::Instruction* inst;
      } Instruction_Object;
      //! pyInstruction type.
	  extern PyTypeObject Instruction_Type;

      PyObject* PyS2EState(s2e::S2EExecutionState* state);
      typedef struct {
        PyObject_HEAD
		s2e::S2EExecutionState *state;
      } S2EState_Object;
      extern PyTypeObject S2EState_Type;

    };
  };
};


/*! Checks if the pyObject is a Instruction. */
#define PyInstruction_Check(v) ((v)->ob_type == &s2e::plugins::python::Instruction_Type)

/*! Returns the Instruction. */
#define PyInstruction_AsInstruction(v) (((s2e::plugins::python::Instruction_Object*)(v))->inst)


/*! Checks if the pyObject is a Instruction. */
#define PyS2EState_Check(v) ((v)->ob_type == &s2e::plugins::python::S2EState_Type)

/*! Returns the Instruction. */
#define PyS2EState_AsS2EExecutionState(v) (((s2e::plugins::python::S2EState_Object*)(v))->state)


#endif /* SRC_S2E_PLUGINS_PYTHON_PYTHONOBJECTS_H_ */
